package wci.backend.interpreter.executors;

import static wci.backend.interpreter.RuntimeErrorCode.UNIMPLEMENTED_FEATURE;
import static wci.intermediate.icodeimpl.ICodeKeyImpl.LINE;
import static wci.message.MessageType.SOURCE_LINE;
import wci.backend.interpreter.Executor;
import wci.intermediate.ICodeNode;
import wci.intermediate.icodeimpl.ICodeNodeTypeImpl;
import wci.message.Message;

/**
 * <h1>StatementExecutor</h1>
 *
 * <p>执行一条语句</p>
 *
 * <p>Copyright (c) 2009 by Ronald Mak</p>
 * <p>For instructional purposes only.  No warranties.</p>
 */
public class StatementExecutor extends Executor
{
    public StatementExecutor(Executor parent)
    {
        super(parent);
    }
    /**
     * 本章中复合和赋值语句返回null值，表达式返回计算后的值
     * @param node 分析树根节点
     * @return 值
     */
    public Object execute(ICodeNode node)
    {
        ICodeNodeTypeImpl nodeType = (ICodeNodeTypeImpl) node.getType();
        sendSourceLineMessage(node);
        switch (nodeType) {
            case COMPOUND: {
                CompoundExecutor compoundExecutor = new CompoundExecutor(this);
                return compoundExecutor.execute(node);
            }
            case ASSIGN: {
                AssignmentExecutor assignmentExecutor =
                    new AssignmentExecutor(this);
                return assignmentExecutor.execute(node);
            }
            case LOOP: {
                LoopExecutor loopExecutor = new LoopExecutor(this);
                return loopExecutor.execute(node);
            }

            case IF: {
                IfExecutor ifExecutor = new IfExecutor(this);
                return ifExecutor.execute(node);
            }

            case SELECT: {
                SelectExecutor selectExecutor = new SelectExecutor(this);
                return selectExecutor.execute(node);
            }
            case NO_OP: return null;
            default: {
                errorHandler.flag(node, UNIMPLEMENTED_FEATURE, this);
                return null;
            }
        }
    }
    /**
     * 将当前要执行的节点的行位置发送出去
     * @param node 要被执行的分析树节点
     */
    private void sendSourceLineMessage(ICodeNode node)
    {
        Object lineNumber = node.getAttribute(LINE);
        if (lineNumber != null) {
            sendMessage(new Message(SOURCE_LINE, lineNumber));
        }
    }
}
